﻿using suirui.ZhuMu.Log;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace suirui.ZhuMu.Common
{
    public class AESUtils
    {
        #region AES加密
        /// <summary>
        /// AES加密
        /// </summary>
        /// <param name="source"></param>
        /// <param name="key">密钥</param>
        /// <param name="iv">初始向量</param>
        /// <param name="padding">填充模式</param>
        /// <param name="mode">加密模式</param>
        /// <returns></returns>
        public static string AESEncrypt(string source, string key, PaddingMode padding = PaddingMode.PKCS7, CipherMode mode = CipherMode.ECB)
        {
            try
            {
                byte[] keyBytes = Encoding.UTF8.GetBytes(key);
                byte[] textBytes = Encoding.UTF8.GetBytes(source);
                //byte[] ivBytes = Encoding.UTF8.GetBytes(key);

                byte[] useKeyBytes = new byte[16];
                //byte[] useIvBytes = new byte[16];

                if (keyBytes.Length > useKeyBytes.Length)
                    Array.Copy(keyBytes, useKeyBytes, useKeyBytes.Length);
                else
                    Array.Copy(keyBytes, useKeyBytes, keyBytes.Length);

                //if (ivBytes.Length > useIvBytes.Length)
                //    Array.Copy(ivBytes, useIvBytes, useIvBytes.Length);
                //else
                //    Array.Copy(ivBytes, useIvBytes, ivBytes.Length);

                Aes aes = System.Security.Cryptography.Aes.Create();
                aes.KeySize = 128;//秘钥的大小，以位为单位,128,256等
                aes.BlockSize = 128;//支持的块大小
                aes.Padding = padding;//填充模式
                aes.Mode = mode;
                aes.Key = useKeyBytes;
                //aes.IV = useIvBytes;//初始化向量，如果没有设置默认的16个0

                ICryptoTransform cryptoTransform = aes.CreateEncryptor();
                byte[] resultBytes = cryptoTransform.TransformFinalBlock(textBytes, 0, textBytes.Length);

                return Convert.ToBase64String(resultBytes);
            }
            catch (Exception ex)
            {
                DefaultLogFactory.Instance.Exception_Loger.Error("解码失败 key=" + key);
                return "";
            }
        }


        /// <summary>
        /// AES加密
        /// </summary>
        /// <param name="str"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string AESEncrypt(string str, string key)
        {
            string result;
            try
            {
                if (string.IsNullOrEmpty(str))
                {
                    result = null;
                }
                else
                {
                    byte[] bytes = Encoding.UTF8.GetBytes(str);
                    RijndaelManaged rijndaelManaged = new RijndaelManaged
                    {
                        Key = Encoding.UTF8.GetBytes(key),
                        Mode = CipherMode.ECB,
                        Padding = PaddingMode.PKCS7
                    };
                    ICryptoTransform cryptoTransform = rijndaelManaged.CreateEncryptor();
                    byte[] array = cryptoTransform.TransformFinalBlock(bytes, 0, bytes.Length);
                    result = Convert.ToBase64String(array, 0, array.Length);

                    return result;
                }
            }
            catch (Exception ex)
            {
                result = null;
                System.Console.WriteLine(ex);
            }
            return result;
        }

        /// <summary>
        /// 使用AES加密字符串,按128位处理key
        /// </summary>
        /// <param name="content">加密内容</param>
        /// <param name="key">秘钥，需要128位、256位.....</param>
        /// <returns>Base64字符串结果</returns>
        public static string AESEncrypt(string content, bool autoHandle = true)
        {
            string key = AppConfigration.Configuration["Encryptionkey"];
            byte[] keyArray = Encoding.UTF8.GetBytes(key);
            if (autoHandle)
            {
                keyArray = GetAesKey(keyArray, key);
            }
            byte[] toEncryptArray = Encoding.UTF8.GetBytes(content);

            SymmetricAlgorithm des = Aes.Create();
            des.Key = keyArray;
            des.Mode = CipherMode.ECB;
            des.Padding = PaddingMode.PKCS7;
            ICryptoTransform cTransform = des.CreateEncryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
            return Convert.ToBase64String(resultArray);
        }

        #endregion

        #region AES解密

        /// <summary>
        /// AES解密
        /// </summary>
        /// <param name="source"></param>
        /// <param name="key">密钥</param>
        /// <param name="iv">初始向量</param>
        /// <param name="padding">填充模式</param>
        /// <param name="mode">加密模式</param>
        /// <returns></returns>
        public static string AESDecrypt(string source, string key, PaddingMode padding = PaddingMode.PKCS7, CipherMode mode = CipherMode.ECB)
        {
            try
            {
                byte[] keyBytes = Encoding.UTF8.GetBytes(key);
                byte[] textBytes = Convert.FromBase64String(source);
                //byte[] ivBytes = SHA256Encrypt2(keyBytes);

                byte[] useKeyBytes = new byte[16];
                //byte[] useIvBytes = new byte[16];

                if (keyBytes.Length > useKeyBytes.Length)
                    Array.Copy(keyBytes, useKeyBytes, useKeyBytes.Length);
                else
                    Array.Copy(keyBytes, useKeyBytes, keyBytes.Length);

                //if (ivBytes.Length > useIvBytes.Length)
                //    Array.Copy(ivBytes, useIvBytes, useIvBytes.Length);
                //else
                //    Array.Copy(ivBytes, useIvBytes, ivBytes.Length);

                Aes aes = System.Security.Cryptography.Aes.Create();
                aes.KeySize = 128;//秘钥的大小，以位为单位,128,256等
                aes.BlockSize = 128;//支持的块大小
                aes.Padding = padding;//填充模式
                aes.Mode = mode;
                aes.Key = useKeyBytes;
                //aes.IV = useIvBytes;//初始化向量，如果没有设置默认的16个0

                ICryptoTransform decryptoTransform = aes.CreateDecryptor();
                byte[] resultBytes = decryptoTransform.TransformFinalBlock(textBytes, 0, textBytes.Length);

                return Encoding.UTF8.GetString(resultBytes);
            }
            catch (Exception ex)
            {
                DefaultLogFactory.Instance.Exception_Loger.Error("AESDecrypt解密失败 key=" + key);
                return "";
            }
        }

        /// <summary>
        /// AES解密
        /// </summary>
        /// <param name="str"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string AESDecrypt(string str, string key)
        {
            if (string.IsNullOrEmpty(str))
            {
                return null;
            }
            string result;
            try
            {
                byte[] array = Convert.FromBase64String(str);

                RijndaelManaged rijndaelManaged = new RijndaelManaged
                {
                    Key = Encoding.UTF8.GetBytes(key),
                    Mode = CipherMode.ECB,
                    Padding = PaddingMode.PKCS7
                };
                ICryptoTransform cryptoTransform = rijndaelManaged.CreateDecryptor();
                byte[] bytes = cryptoTransform.TransformFinalBlock(array, 0, array.Length);
                result = Encoding.UTF8.GetString(bytes);
            }
            catch (Exception ex)
            {
                result = null;
                Console.WriteLine(ex);
            }
            return result;
        }

        /// <summary>
        /// 使用AES解密字符串,按128位处理key
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="key">秘钥，需要128位、256位.....</param>
        /// <returns>UTF8解密结果</returns>
        public static string AESDecrypt(string content, bool autoHandle = true)
        {
            try
            {
                string key = AppConfigration.Configuration["Encryptionkey"];
                byte[] keyArray = Encoding.UTF8.GetBytes(key);
                if (autoHandle)
                {
                    keyArray = GetAesKey(keyArray, key);
                }
                if (autoHandle)
                {
                    keyArray = GetAesKey(keyArray, key);
                }
                byte[] toEncryptArray = Convert.FromBase64String(content);

                SymmetricAlgorithm des = Aes.Create();
                des.Key = keyArray;
                des.Mode = CipherMode.ECB;
                des.Padding = PaddingMode.PKCS7;

                ICryptoTransform cTransform = des.CreateDecryptor();
                byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

                return Encoding.UTF8.GetString(resultArray);
            }
            catch (Exception)
            {
                return "";
                throw;
            }
        }
        #endregion

        /// <summary>
        /// 128位处理key 
        /// </summary>
        /// <param name="keyArray">原字节</param>
        /// <param name="key">处理key</param>
        /// <returns></returns>
        private static byte[] GetAesKey(byte[] keyArray, string key)
        {
            byte[] newArray = new byte[16];
            if (keyArray.Length < 16)
            {
                for (int i = 0; i < newArray.Length; i++)
                {
                    if (i >= keyArray.Length)
                    {
                        newArray[i] = 0;
                    }
                    else
                    {
                        newArray[i] = keyArray[i];
                    }
                }
            }
            return newArray;
        }
    }
}
